/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package minpath;

import base.JGrafo;
import base.Vertice;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.HashMap;
import minpath.bellmanford.BellmanFord;
import minpath.dijkstra.Dijkstra;

/**
 *
 * @author diego
 */
public class ProductionLines {

    public static void main(String args[]) {
        // 2st production line:

        HashMap<AbstractMap.SimpleEntry<Vertice, Vertice>, Integer> weights = new HashMap<>();

        Vertice origem = new Vertice("e");
        Vertice destino = new Vertice("x");

        ArrayList<Vertice> linha1 = new ArrayList<>();
        linha1.add(new Vertice("S11"));
        linha1.add(new Vertice("S12"));
        linha1.add(new Vertice("S13"));
        linha1.add(new Vertice("S14"));
        linha1.add(new Vertice("S15"));
        linha1.add(new Vertice("S16"));
        linha1.add(new Vertice("S17"));
        linha1.add(new Vertice("S18"));
        linha1.add(new Vertice("S19"));
        linha1.add(new Vertice("S110"));

        ArrayList<Vertice> linha2 = new ArrayList<>();
        linha2.add(new Vertice("S21"));
        linha2.add(new Vertice("S22"));
        linha2.add(new Vertice("S23"));
        linha2.add(new Vertice("S24"));
        linha2.add(new Vertice("S25"));
        linha2.add(new Vertice("S26"));
        linha2.add(new Vertice("S27"));
        linha2.add(new Vertice("S28"));
        linha2.add(new Vertice("S29"));
        linha2.add(new Vertice("S210"));

        ArrayList<Vertice> vertices = new ArrayList<>();
        vertices.add(origem);
        for (int i = 0; i < linha1.size() && i < linha2.size(); i ++) {
            vertices.add(linha1.get(i));
            vertices.add(linha2.get(i));
        }
        vertices.add(destino);

        JGrafo g = new JGrafo(vertices);

        // origem
        g.add_edge(origem, linha1.get(0));
        weights.put(new AbstractMap.SimpleEntry<>(origem, linha1.get(0)), 3);
        g.add_edge(origem, linha2.get(0));
        weights.put(new AbstractMap.SimpleEntry<>(origem, linha2.get(0)), 2);

        // linha 1
        // S11
        g.add_edge(linha1.get(0), linha1.get(1));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(0), linha1.get(1)), 5);
        g.add_edge(linha1.get(0), linha2.get(1));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(0), linha2.get(1)), 8);

        // S12
        g.add_edge(linha1.get(1), linha1.get(2));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(1), linha1.get(2)), 7);
        g.add_edge(linha1.get(1), linha2.get(2));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(1), linha2.get(2)), 12);

        // S13
        g.add_edge(linha1.get(2), linha1.get(3));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(2), linha1.get(3)), 10);
        g.add_edge(linha1.get(2), linha2.get(3));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(2), linha2.get(3)), 14);

        // S14
        g.add_edge(linha1.get(3), linha1.get(4));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(3), linha1.get(4)), 5);
        g.add_edge(linha1.get(3), linha2.get(4));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(3), linha2.get(4)), 7);

        // S15
        g.add_edge(linha1.get(4), linha1.get(5));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(4), linha1.get(5)), 9);
        g.add_edge(linha1.get(4), linha2.get(5));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(4), linha2.get(5)), 16);

        // S16
        g.add_edge(linha1.get(5), linha1.get(6));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(5), linha1.get(6)), 11);
        g.add_edge(linha1.get(5), linha2.get(6));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(5), linha2.get(6)), 16);

        // S17
        g.add_edge(linha1.get(6), linha1.get(7));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(6), linha1.get(7)), 9);
        g.add_edge(linha1.get(6), linha2.get(7));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(6), linha2.get(7)), 17);

        // S18
        g.add_edge(linha1.get(7), linha1.get(8));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(7), linha1.get(8)), 5);
        g.add_edge(linha1.get(7), linha2.get(8));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(7), linha2.get(8)), 6);

        // S19
        g.add_edge(linha1.get(8), linha1.get(9));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(8), linha1.get(9)), 2);

        // linha 2
        // S21
        g.add_edge(linha2.get(0), linha2.get(1));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(0), linha2.get(1)),6);
        g.add_edge(linha2.get(0), linha1.get(1));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(0), linha1.get(1)),11);

        // S22
        g.add_edge(linha2.get(1), linha2.get(2));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(1), linha2.get(2)),3);
        g.add_edge(linha2.get(1), linha1.get(2));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(1), linha1.get(2)),6);

        // S23
        g.add_edge(linha2.get(2), linha2.get(3));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(2), linha2.get(3)),9);
        g.add_edge(linha2.get(2), linha1.get(3));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(2), linha1.get(3)),16);

        // S24
        g.add_edge(linha2.get(3), linha2.get(4));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(3), linha2.get(4)),11);
        g.add_edge(linha2.get(3), linha1.get(4));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(3), linha1.get(4)),16);

        // S25
        g.add_edge(linha2.get(4), linha2.get(5));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(4), linha2.get(5)),4);
        g.add_edge(linha2.get(4), linha1.get(5));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(4), linha1.get(5)),10);

        // S26
        g.add_edge(linha2.get(5), linha2.get(6));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(5), linha2.get(6)),9);
        g.add_edge(linha2.get(5), linha1.get(6));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(5), linha1.get(6)),11);

        // S27
        g.add_edge(linha2.get(6), linha2.get(7));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(6), linha2.get(7)),3);
        g.add_edge(linha2.get(6), linha1.get(7));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(6), linha1.get(7)),8);

        // S28
        g.add_edge(linha2.get(7), linha2.get(8));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(7), linha2.get(8)),12);
        g.add_edge(linha2.get(7), linha1.get(8));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(7), linha1.get(8)),14);

        // S29
        g.add_edge(linha2.get(8), linha2.get(9));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(8), linha2.get(9)),4);
        
        // destino
        g.add_edge(linha1.get(9), destino);
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(9), destino), 6);
        g.add_edge(linha2.get(9), destino);
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(9), destino), 5);
        
        System.out.println("Menor caminho usando dijkstra entre a entrada e a saída da linha de produção 1: ");
        String path = "";
        HashMap<Vertice, ArrayList<Vertice>> result_set = Dijkstra.dijkstra(g, weights, origem);
        for (int i = (result_set.get(destino).size() - 1); i >= 0; i --) {
            path += result_set.get(destino).get(i).name + ", ";
        }
        System.out.println(path);
        System.out.println("Custo: "+destino.key);
        
        System.out.println("Menor caminho usando Bellman-Ford entre a entrada e a saída da linha de produção 1: ");
        path = "";
        result_set = BellmanFord.bellmanFord(g, weights, origem);
        for (int i = (result_set.get(destino).size() - 1); i >= 0; i --) {
            path += result_set.get(destino).get(i).name + ", ";
        }
        System.out.println(path);
        System.out.println("Custo: "+destino.key);
        
        // GRAFO 2:
        
        weights = new HashMap<>();
        origem = new Vertice("e");
        destino = new Vertice("x");
        
        linha1 = new ArrayList<>();
        linha1.add(new Vertice("S11"));
        linha1.add(new Vertice("S12"));
        linha1.add(new Vertice("S13"));
        linha1.add(new Vertice("S14"));
        linha1.add(new Vertice("S15"));
        linha1.add(new Vertice("S16"));
        linha1.add(new Vertice("S17"));
        linha1.add(new Vertice("S18"));
        linha1.add(new Vertice("S19"));
        
        linha2 = new ArrayList<>();
        linha2.add(new Vertice("S21"));
        linha2.add(new Vertice("S22"));
        linha2.add(new Vertice("S23"));
        linha2.add(new Vertice("S24"));
        linha2.add(new Vertice("S25"));
        linha2.add(new Vertice("S26"));
        linha2.add(new Vertice("S27"));
        linha2.add(new Vertice("S28"));
        linha2.add(new Vertice("S29"));
        
        vertices = new ArrayList<>();
        vertices.add(origem);
        for (int i = 0; i < linha1.size() && i < linha2.size(); i ++) {
            vertices.add(linha1.get(i));
            vertices.add(linha2.get(i));
        }
        vertices.add(destino);
        
        g = new JGrafo(vertices);

        // origem
        g.add_edge(origem, linha1.get(0));
        weights.put(new AbstractMap.SimpleEntry<>(origem, linha1.get(0)), 5);
        g.add_edge(origem, linha2.get(0));
        weights.put(new AbstractMap.SimpleEntry<>(origem, linha2.get(0)), 7);

        // linha 1
        // S11
        g.add_edge(linha1.get(0), linha1.get(1));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(0), linha1.get(1)), 10);
        g.add_edge(linha1.get(0), linha2.get(1));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(0), linha2.get(1)), 14);

        // S12
        g.add_edge(linha1.get(1), linha1.get(2));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(1), linha1.get(2)), 6);
        g.add_edge(linha1.get(1), linha2.get(2));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(1), linha2.get(2)), 8);

        // S13
        g.add_edge(linha1.get(2), linha1.get(3));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(2), linha1.get(3)), 3);
        g.add_edge(linha1.get(2), linha2.get(3));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(2), linha2.get(3)), 10);

        // S14
        g.add_edge(linha1.get(3), linha1.get(4));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(3), linha1.get(4)), 8);
        g.add_edge(linha1.get(3), linha2.get(4));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(3), linha2.get(4)), 10);

        // S15
        g.add_edge(linha1.get(4), linha1.get(5));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(4), linha1.get(5)), 5);
        g.add_edge(linha1.get(4), linha2.get(5));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(4), linha2.get(5)), 10);

        // S16
        g.add_edge(linha1.get(5), linha1.get(6));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(5), linha1.get(6)), 3);
        g.add_edge(linha1.get(5), linha2.get(6));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(5), linha2.get(6)), 11);

        // S17
        g.add_edge(linha1.get(6), linha1.get(7));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(6), linha1.get(7)), 7);
        g.add_edge(linha1.get(6), linha2.get(7));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(6), linha2.get(7)), 9);

        // S18
        g.add_edge(linha1.get(7), linha1.get(8));
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(7), linha1.get(8)), 12);
        
        // linha 2
        // S21
        g.add_edge(linha2.get(0), linha2.get(1));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(0), linha2.get(1)),3);
        g.add_edge(linha2.get(0), linha1.get(1));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(0), linha1.get(1)),9);

        // S22
        g.add_edge(linha2.get(1), linha2.get(2));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(1), linha2.get(2)),5);
        g.add_edge(linha2.get(1), linha1.get(2));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(1), linha1.get(2)),6);

        // S23
        g.add_edge(linha2.get(2), linha2.get(3));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(2), linha2.get(3)),3);
        g.add_edge(linha2.get(2), linha1.get(3));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(2), linha1.get(3)),10);

        // S24
        g.add_edge(linha2.get(3), linha2.get(4));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(3), linha2.get(4)),7);
        g.add_edge(linha2.get(3), linha1.get(4));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(3), linha1.get(4)),10);

        // S25
        g.add_edge(linha2.get(4), linha2.get(5));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(4), linha2.get(5)),6);
        g.add_edge(linha2.get(4), linha1.get(5));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(4), linha1.get(5)),12);

        // S26
        g.add_edge(linha2.get(5), linha2.get(6));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(5), linha2.get(6)),4);
        g.add_edge(linha2.get(5), linha1.get(6));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(5), linha1.get(6)),8);

        // S27
        g.add_edge(linha2.get(6), linha2.get(7));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(6), linha2.get(7)),9);
        g.add_edge(linha2.get(6), linha1.get(7));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(6), linha1.get(7)),14);

        // S28
        g.add_edge(linha2.get(7), linha2.get(8));
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(7), linha2.get(8)),10);
        
        // destino
        g.add_edge(linha1.get(8), destino);
        weights.put(new AbstractMap.SimpleEntry<>(linha1.get(8), destino), 8);
        g.add_edge(linha2.get(8), destino);
        weights.put(new AbstractMap.SimpleEntry<>(linha2.get(8), destino), 9);
        
        System.out.println("Menor caminho usando dijkstra entre a entrada e a saída da linha de produção 2: ");
        path = "";
        result_set = Dijkstra.dijkstra(g, weights, origem);
        for (int i = (result_set.get(destino).size() - 1); i >= 0; i --) {
            path += result_set.get(destino).get(i).name + ", ";
        }
        System.out.println(path);
        System.out.println("Custo: "+destino.key);
        
        System.out.println("Menor caminho usando Bellman-Ford entre a entrada e a saída da linha de produção 2: ");
        path = "";
        result_set = BellmanFord.bellmanFord(g, weights, origem);
        for (int i = (result_set.get(destino).size() - 1); i >= 0; i --) {
            path += result_set.get(destino).get(i).name + ", ";
        }
        System.out.println(path);
        System.out.println("Custo: "+destino.key);
    }
}
